﻿using CardPlay.Model.CardModel;
using CardPlay.Model.GameModel;
using CardPlay.Model.GameModel.Presentation;
using CardPlay.Model.Layout;
using CardPlay.Model.Primitives;

namespace CardPlay.DemoPack.Games.FourSeasonsVariants
{
    [Game("0E169490-7731-4394-BB4B-529D79F7B50B", LevelOfDifficulty.Medium, LevelOfSkill.MostlyChance, DurationOfPlay.Within5To10Minutes, Family = FamilyName)]
    public class FourSeasons : StandardCardGame
    {
        public const string FamilyName = "Four Seasons";

        public FourSeasons()
        {
            NamesOfAdditionalPiles.AddRange(new [] {Stock, Waste});

            CardsPerDeal = 1;
            MaximumDeals = 1;

            TotalTableaus = 5;
            TableauBuildSequence = CardFaceSequence.AnySuitDescendingRank;
        }

        public override ILayoutSite CreatePresentation(IPresentationContext presentation)
        {
            var root = presentation.CreateRowLayout();

            var stockWaste = presentation.CreateStockWasteLayout(this);
            root.Add(stockWaste);

            stockWaste.Direction = SpreadDirection.Vertical;

            var centerLayout = new UniformGridLayout { Columns = 3, Rows = 3 };
            root.Add(centerLayout);

            var minimumSize = presentation.Metrics.CardSize + new Size(presentation.Metrics.MinSpacingAcross * 2, presentation.Metrics.MinSpacingAcross * 2);

            // Top row
            centerLayout.Add(presentation.CreatePileVisual(Foundation1, AugmentStyle(presentation, HorizontalAlignment.Right, VerticalAlignment.Bottom, minimumSize)));
            centerLayout.Add(presentation.CreatePileVisual(Tableau1, AugmentStyle(presentation, HorizontalAlignment.Center, VerticalAlignment.Top, minimumSize, false)));
            centerLayout.Add(presentation.CreatePileVisual(Foundation2, AugmentStyle(presentation, HorizontalAlignment.Left, VerticalAlignment.Bottom, minimumSize)));

            // Middle row
            centerLayout.Add(presentation.CreatePileVisual(Tableau2, AugmentStyle(presentation, HorizontalAlignment.Left, VerticalAlignment.Center, minimumSize, false)));
            centerLayout.Add(presentation.CreatePileVisual(Tableau3, AugmentStyle(presentation, HorizontalAlignment.Center, VerticalAlignment.Center, minimumSize, false)));
            centerLayout.Add(presentation.CreatePileVisual(Tableau4, AugmentStyle(presentation, HorizontalAlignment.Right, VerticalAlignment.Center, minimumSize, false)));

            // Bottom row
            centerLayout.Add(presentation.CreatePileVisual(Foundation3, AugmentStyle(presentation, HorizontalAlignment.Right, VerticalAlignment.Top, minimumSize)));
            centerLayout.Add(presentation.CreatePileVisual(Tableau5, AugmentStyle(presentation, HorizontalAlignment.Center, VerticalAlignment.Bottom, minimumSize, false)));
            centerLayout.Add(presentation.CreatePileVisual(Foundation4, AugmentStyle(presentation, HorizontalAlignment.Left, VerticalAlignment.Top, minimumSize)));

            return root;
        }

        protected override void PrepareDealScript(DealScript script)
        {
            PrepareDealScriptForFoundations(script);
            script.DealToEach(NamesOfTableaus, "up");
            script.DealRemainingFaceDownTo(Stock);
        }

        protected virtual void PrepareDealScriptForFoundations(DealScript script)
        {
            script.Deal("up").To(Foundation1);
        }

        protected VisualTraits AugmentStyle(IPresentationContext presentation, HorizontalAlignment horizontalAlignment, VerticalAlignment verticalAlignment, Size minimumSize, bool isFoundation = true)
        {
            var style = isFoundation 
                ? presentation.StyleForRepeatedRankFoundation(this, FoundationBaseRank, TotalDecks)
                : StandardStyles.Foundation;

            style.MinimumSize = minimumSize;
            style.HorizontalAlignment = horizontalAlignment;
            style.VerticalAlignment = verticalAlignment;

            if (!isFoundation) style.EmptyCue = () => EmptyPileCue.Outlined;

            return style;
        }
    }
}
